package com.gwt.boot.tools;


import com.alibaba.fastjson.JSONObject;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 递归工具
 */
public class TreeTools {

    private final TreeConfig treeConfig;

    private TreeTools(String idKey, String parentIdKey, String childrenKey) {
        this.treeConfig = new TreeConfig(idKey, parentIdKey, childrenKey);
    }

    /**
     * 配置递归参数
     * @param idKey 主键ID的key
     * @param parentIdKey 父级ID的key
     * @param childrenKey 子类集合的key
     * @return TreeTools
     */
    public static TreeTools config(String idKey, String parentIdKey, String childrenKey){
        return new TreeTools(idKey, parentIdKey, childrenKey);
    }

    /**
     * 递归
     * @param list 原数据
     * @param clazz 转换的类型
     * @param parentId 父节点ID
     * @return List
     * @param <T> T
     */
    public <T> List<T> tree(List<?> list, Class<T> clazz, Object parentId) {
        List<T> result = new ArrayList<>();
        Optional.ofNullable(list).orElse(new ArrayList<>())
                .stream().filter(item -> Objects.equals(parentId.toString(), JSONObject.parseObject(JSONObject.toJSONString(item)).getString(treeConfig.getParentIdKey()))).collect(Collectors.toList())
                .forEach(item -> {
                    JSONObject self = JSONObject.parseObject(JSONObject.toJSONString(item));
                    if (Objects.equals(parentId.toString(), self.getString(treeConfig.getParentIdKey()))){
                        List<T> childList = tree(list, clazz, self.get(treeConfig.getIdKey()));
                        if (childList != null && childList.size() > 0) {
                            self.put(treeConfig.getChildrenKey(), childList);
                        }
                        result.add(JSONObject.toJavaObject(self, clazz));
                    }
                });
        return result;
    }
}

/**
 * 配置通用递归参数
 */
@Data
class TreeConfig{
    public TreeConfig(String idKey, String parentIdKey, String childrenKey) {
        this.idKey = idKey;
        this.parentIdKey = parentIdKey;
        this.childrenKey = childrenKey;
    }

    /**
     * 数据行自己的ID名称
     */
    private String idKey;

    /**
     * 数据行父级的ID名称
     */
    private String parentIdKey;

    /**
     * 存放下级集合的key名称
     */
    private String childrenKey;
}